#include<stdio.h>
#include<stdlib.h>
#include<conio.h>
#include<windows.h>

#define High 15 //游戏画面尺寸
#define Width 35

//全局变量
int food_x,food_y;     //记录事物的位置
int moveDirection;		//	小蛇移动方向，1,2,3,4，分别表示上下左右
int canvas[High][Width]={0};  //二维数组存储游戏画布中对应的元素
					//0为空格，-1为边框#，1为蛇头@，>1为蛇身，-2为食物
void gotoxy(int x, int y)   //光标移动到(x,y)位置
{
	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
	COORD pos;
	pos.X = x;
	pos.Y = y;
	SetConsoleCursorPosition(handle,pos);
}

void startup()  //数据初始化
{
	int i,j;
	//以下设定边框的数值
	for(i=0;i<High;i++)
	{
		canvas[i][o]=-1;
		canvas[i][Width-1]=-1;
	}
		for(j=0;j<Width;j++)
	{
		canvas[0][j]=-1;
		canvas[High-1][j]=-1;
	}
	//以下初始化蛇头蛇身
	canvs[High/2][Width/2]=1;
	for(i=1;i<=8;i++)
		canvas[High/2][Width/2-i]=i+1;
	//初始化小蛇移动方向向右
	moveDirection = 4;
	//初始化食物的位置
	food_x=rand() % (High-5)+2;
	food_y=rand() % (Width-5)+2;
	canvas[food_x][food_y]=-2;

}

void moveSnakeDirection()
{
	int i,j;
	int max=0;
	int oldTail_i,oldTail_j;  //记录旧蛇尾
	int oldHead_i,oldHead_j;  //记录旧蛇头
	for(i=1;i<High-1;i++)
		for(j=1;j<Width-1;j++)
		{
			//对所有大于0的元素+1
			if(canvas[i][j]>0)
			{
				canvas[i][j]++;	
				//求出最大值max
				if(max<canvas[i][j])
				{
					max=canvas[i][j];
					oldTail_i=i;
					oldTail_j=j;
				}
				
				//记录旧蛇头位置
				if(canvas[i][j]==2)
				{
					oldHead_i=i;
					oldHead_j=j;
				}
			}
		}
	int newHead_i,newHead_j;

	if(moveDirection==1) //向上
	{
		newHead_i=oldHead_i-1;
		newHead_j=oldHead_j;
	}
		
	if(moveDirection==2) //向下
	{
		newHead_i=oldHead_i+1;
		newHead_j=oldHead_j;
	}
	if(moveDirection==3) //向左
	{
		newHead_i=oldHead_i;
		newHead_j=oldHead_j-1;
	}
	if(moveDirection==4) //向右
	{
		newHead_i=oldHead_i;
		newHead_j=oldHead_j+1;
	}
	//判断小蛇蛇头是否碰到食物
	if(canvas[newHead_i][newHead_j]==-2)
	{	
	//食物原始位置归0
	canvas[food_x][food_y]=0 ;
	//产生新的食物
	food_x=rand() % (High-5)+2 ;
	food_y=rand() % (Width-5)+2 ;
	canvas[food_x][food_y]=-2 ;
	//吃到食物，不用把最大值设0
	}
	else
	{
	
	}
	//判断小蛇蛇头撞到边框或自身，游戏失败
	if (canvas[newHead_i][newHead_j]>0 || canvas[newHead_i][newHead_j]==-1)
	{
		printf("游戏失败\n");
		exit(0);
	}

	else
	{
		//没有吃到食物的时候，长度不变
		canvas[newHead_i][newHead_j]=0;   //最大值所在元素变为0
	}

}

void show()  //显示画面
{
	gotoxy(0,0);  //光标移动到原点位置，以下重画清屏
	int i,j;
	for(i=0;i<High;i++)
	{
		for(j=0;j<Width;j++)
		{
			if(canvas[i][j]==0)
				printf(" ");  //输出空格
			else if(canvas[i][j]==-1)
				printf("#");  //输出边框
			else if(canvas[i][j]==1)
				printf("@");  //输出蛇头
			else if(canvas[i][j]>1)
				printf("*");  //输出蛇身
			Sleep(100);
		}
	}
}

void updateWithoutInput()  //与用户输入无关的更新
{
	moveSnakeByDirection();
}

void updateWithInput()  //与用户输入有关的更新
{
	char input;
	if(kbhit())		//判断是否有输入
	{
		input=getch();		//根据用户的不同输入
		if(input=='a')
			moveDirection=3;
		if(input=='s')
			moveDirection=2;
		if(input=='w')
			moveDirection=1;
		if(input=='d')
			moveDirection=4;
	}
}

int main()
{
	startup;  //数据初始化
	while(1)  //游戏循环执行
	{
		show();
		updateWithInput();
		updateWithoutInput();
	}
	return 0;
}